//
// Listing 2: Grundlegende Mock-Objekte
//

#include "interface.h"
#include "consumer.h"

#include <mockpp/MockObject.h>
#include <mockpp/ExpectationList.h>
#include <mockpp/ReturnObjectList.h>
#include <mockpp/ExpectationCounter.h>

#include <exception>
#include <iostream>


class BasicMock : public Interface
                , public MOCKPP_NS::MockObject
{
  public:

    BasicMock()
      : MOCKPP_NS::MockObject(MOCKPP_PCHAR("BasicMock"), 0)
      , open_name(MOCKPP_PCHAR("BasicMock/open_name"), this)
      , close_counter(MOCKPP_PCHAR("BasicMock/close_counter"), this)
      , write_data(MOCKPP_PCHAR("BasicMock/write_data"), this)
      , read_data(MOCKPP_PCHAR("BasicMock/read_data"), this)
    {
    }

    virtual void open(const MOCKPP_STD_NS::string &name)
    {
      open_name.addActual(name);
    }

    virtual MOCKPP_STD_NS::string read()
    {
      return read_data.nextReturnObject();
    }

    virtual void write(const MOCKPP_STD_NS::string &s)
    {
      write_data.addActual(s);
    }

    virtual void close()
    {
      close_counter.inc();
    }

    MOCKPP_NS::ExpectationList<MOCKPP_STD_NS::string>  open_name;
    MOCKPP_NS::ExpectationCounter            close_counter;
    MOCKPP_NS::ExpectationList<MOCKPP_STD_NS::string>  write_data;
    MOCKPP_NS::ReturnObjectList<MOCKPP_STD_NS::string> read_data;
};


int main(int argc, char **argv)
{
  try
  {
    BasicMock mock;

    // Jeweils �ffnen beim Lesen und Schreiben
    mock.open_name.addExpected("datei1.lst");
    mock.open_name.addExpected("datei1.lst");

    // Jeweils schliessen beim Lesen und Schreiben
    mock.close_counter.setExpected(2);

    // Die Datei enth�lt genau 3 Zeilen Daten
    mock.read_data.addObjectToReturn("Datenpaket-1");
    mock.read_data.addObjectToReturn("Datenpaket-2");
    mock.read_data.addObjectToReturn("Datenpaket-3");

    // Es werden wieder genau 3 Zeilen Daten zur�ckgeschrieben
    mock.write_data.addExpected("Datenpaket-1/fertig");
    mock.write_data.addExpected("Datenpaket-2/fertig");
    mock.write_data.addExpected("Datenpaket-3/fertig");

    // Consumer-Klasse ablaufen lassen
    MOCKPP_STD_NS::cout << "Start der Tests" << MOCKPP_STD_NS::endl;

    Consumer consumer(&mock);
    consumer.load();
    consumer.process();
    consumer.save();

    MOCKPP_STD_NS::cout << "Ende der Tests" << MOCKPP_STD_NS::endl;

    // alle restlichen Bedingungen pr�fen
    mock.verify();
    MOCKPP_STD_NS::cout << "Alle Tests wurden fehlerfrei durchlaufen" << MOCKPP_STD_NS::endl;
  }
  catch(MOCKPP_STD_NS::exception &ex)
  {
    MOCKPP_STD_NS::cout << MOCKPP_STD_NS::endl
              << "Fehler aufgetreten.\n" << ex.what() << MOCKPP_STD_NS::endl
              << MOCKPP_STD_NS::endl;
  }
}
